/*
 * sys_monitor.c
 *
 *  Created on: 2023年4月17日
 *      Author: Lw
 */
#include "sys_monitor.h"
#include "xsysmonpsu.h"
#include "xwdtps.h"
#include "ff.h"
static XSysMonPsu SysMonInst;      /* System Monitor driver instance */
#define SYSMON_DEVICE_ID 	XPAR_XSYSMONPSU_0_DEVICE_ID
XSysMonPsu *SysMonInstPtr = &SysMonInst;
XWdtPs Watchdog;		/* Instance of WatchDog Timer  */
static FIL fil;     /* File object */

u16 readResetReason(void);
void sysMonitorInit(void)
{
    FRESULT rc;
    UINT br;
    UINT bw;

    /*系统参数存储文件*/
    rc = f_open(&fil, EMMC_SYS_MONIT_PARAM_FILE, FA_OPEN_EXISTING);
    if(rc != FR_OK){
        rc = f_open(&fil, EMMC_SYS_MONIT_PARAM_FILE, FA_CREATE_ALWAYS | FA_WRITE);
		f_lseek(&fil, 0);
		s_SysMonit.SysResetTotalNum = 0;
		s_SysMonit.WdtResetCount = 0;
		s_SysMonit.WdtTimeOver = 30;
		s_SysMonit.WdtEnable = 0;
		rc = f_write(&fil, &s_SysMonit, sizeof(s_SysMonit), &bw);
    }
    /* 从emmc中读出数据  */
    rc = f_open(&fil, EMMC_SYS_MONIT_PARAM_FILE, FA_READ);
    rc = f_read(&fil, &s_SysMonit, sizeof(s_SysMonit), &br);
    if(rc != FR_OK){
        f_close(&fil);
    }
    f_close(&fil);

    if(readResetReason() != SYS_RESET_REASON_POR){
    	s_SysMonit.WdtResetCount ++;
    }
    s_SysMonit.SysResetTotalNum ++;
	f_open(&fil, EMMC_SYS_MONIT_PARAM_FILE, FA_OPEN_EXISTING | FA_WRITE);
	f_lseek(&fil, 0);
	f_write(&fil, &s_SysMonit, sizeof(s_SysMonit), &bw);
	f_close(&fil);

	XSysMonPsu_Config *ConfigPtr;
	/* Initialize the SysMon driver. */
	ConfigPtr = XSysMonPsu_LookupConfig(SYSMON_DEVICE_ID);
	XSysMonPsu_CfgInitialize(SysMonInstPtr, ConfigPtr,ConfigPtr->BaseAddress);
	wdtInit(s_SysMonit.WdtTimeOver, s_SysMonit.WdtEnable);
	s_SysRev.SaveFlag = 0;
	s_SysRev.TestFlag = 0;
}

/*Read the on-chip Temperature Data*/
char readPrepTemp(void)
{
	u32 TempRawData;
	int TempData;
	TempRawData = XSysMonPsu_GetAdcData(SysMonInstPtr, XSM_CH_TEMP, XSYSMON_PS);
	TempData = (int)XSysMonPsu_RawToTemperature_OnChip(TempRawData);
	return (char)TempData;
}

void SysParamSave(void)
{
    UINT bw;
	if(s_SysRev.SaveFlag == 1)
	{
		s_SysRev.SaveFlag = 0;
		f_open(&fil, EMMC_SYS_MONIT_PARAM_FILE, FA_OPEN_EXISTING | FA_WRITE);
		f_lseek(&fil, 0);
		f_write(&fil, &s_SysMonit, sizeof(s_SysMonit), &bw);
		f_close(&fil);
	}
}


//读取系统复位原因
u16 readResetReason(void)
{
    u16 CrlResetReason =  Xil_In16(CRL_APB_RESET_REASON);
    xil_printf("CrlResetReason = %d\n\r", CrlResetReason);

	return CrlResetReason;
}     

//看门狗打开，配置超时时间 s 为timeOver,enable=1使能复位，else 不使能复位
void wdtInit(u16 timeOver, u8 enable)
{

	XWdtPs_Config *ConfigPtr;
	u32 EffectiveAddress;	/* This can be the virtual address */

	ConfigPtr = XWdtPs_LookupConfig(XPAR_XWDTPS_1_DEVICE_ID);
	EffectiveAddress = ConfigPtr->BaseAddress;
	XWdtPs_CfgInitialize(&Watchdog, ConfigPtr,EffectiveAddress);

	XWdtPs_SetControlValue(&Watchdog,(u8) XWDTPS_COUNTER_RESET, (timeOver*50));//1000 is 20s
	XWdtPs_SetControlValue(&Watchdog,(u8) XWDTPS_CLK_PRESCALE, XWDTPS_CCR_PSCALE_0512);//
	if(enable == 1){
		XWdtPs_EnableOutput(&Watchdog, XWDTPS_RESET_SIGNAL);
	}
	else{
		XWdtPs_DisableOutput(&Watchdog, XWDTPS_RESET_SIGNAL);
	}

	XWdtPs_Start(&Watchdog);
	XWdtPs_RestartWdt(&Watchdog);
}

//看门狗喂狗
void wdtFeed(void)
{
	XWdtPs_RestartWdt(&Watchdog);
}


static u16 WdtTimeCunt = 0;
void wdtFeedProcess(void)
{
	WdtTimeCunt++;
	if(WdtTimeCunt >= (s_SysMonit.WdtTimeOver/3) && s_SysRev.TestFlag == 0){
		WdtTimeCunt = 0;
		wdtFeed();
	}
}
